﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BreukTrainer.Model
{
    delegate Breuk DelegateBreukenBewerking(Breuk breuk1, Breuk breuk2);
    class ProgrammeerbareBreukContainer : BreukContainer
    {
        /// <summary>
        /// Methode om een bewerking te doen met alle Breuken van de verzameling
        /// </summary>
        /// <param name="delegateBreukenBewerking">Delegate Bewerking</param>
        /// <returns>Breuk</returns>
        public Breuk DoeBewerking(DelegateBreukenBewerking delegateBreukenBewerking)
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++)
            {
                b = delegateBreukenBewerking(b, breuken[i]);
            }
            return b;
        }

        /// <summary>
        /// Methode om een bewerking te doen met een meegegeven aantal Breuken van de verzameling
        /// </summary>
        /// <param name="delegateBreukenBewerking">Delegate Bewerking</param>
        /// <param name="aantal">Aantal</param>
        /// <returns>Breuk</returns>
        public Breuk DoeBewerking(DelegateBreukenBewerking delegateBreukenBewerking, int aantal)
        {
            if (aantal > breuken.Count)
            {
                return DoeBewerking(delegateBreukenBewerking);
            }
            else
            {
                Breuk b = breuken[0];
                for (int i = 1; i < aantal; i++)
                {
                    b = delegateBreukenBewerking(b, breuken[i]);
                }
                return b;
            }
        }

        /// <summary>
        /// Methode om een verzameling operanden een bewerking laten doen met alle Breuken van de verzameling
        /// </summary>
        /// <param name="delegateBreukenBewerking">Delegate Bewerking</param>
        /// <param name="operanden">Verzameling Operanden</param>
        /// <returns>Breuken-array</returns>
        public Breuk[] DoeBewerking(DelegateBreukenBewerking[] delegateBreukenBewerking, String[] operanden)
        {
            Breuk[] result = new Breuk[operanden.Count()];
            for (int i = 0; i < operanden.Count(); i++)
            {
                switch (operanden[i])
                {
                    case "+":
                        result[i] = DoeBewerking(delegateBreukenBewerking[i]);
                        break;
                    case "-":
                        result[i] = DoeBewerking(delegateBreukenBewerking[i]);
                        break;
                    case "*":
                        result[i] = DoeBewerking(delegateBreukenBewerking[i]);
                        break;
                    case "/":
                        result[i] = DoeBewerking(delegateBreukenBewerking[i]);
                        break;
                }
            }
            return result;
        }

        /// <summary>
        /// Methode om een meegegeven aantal operanden een bewerking laten doen met een meegegeven aantal Breuken van de verzameling
        /// </summary>
        /// <param name="delegateBreukenBewerking">Delegate Bewerking</param>
        /// <param name="operanden">Verzameling Operanden</param>
        /// <param name="aantal">Aantal</param>
        /// <returns>Breuken-array</returns>
        public Breuk[] DoeBewerking(DelegateBreukenBewerking[] delegateBreukenBewerking, String[] operanden, int aantal)
        {
            if (aantal > breuken.Count)
            {
                return DoeBewerking(delegateBreukenBewerking, operanden);
            }
            else
            {
                Breuk[] result = new Breuk[aantal];
                for (int i = 0; i < aantal; i++)
                {
                    switch (operanden[i])
                    {
                        case "+":
                            result[i] = DoeBewerking(delegateBreukenBewerking[i], aantal);
                            break;
                        case "-":
                            result[i] = DoeBewerking(delegateBreukenBewerking[i], aantal);
                            break;
                        case "*":
                            result[i] = DoeBewerking(delegateBreukenBewerking[i], aantal);
                            break;
                        case "/":
                            result[i] = DoeBewerking(delegateBreukenBewerking[i], aantal);
                            break;
                    }
                }
                return result;
            }
        }

        public Breuk TestIets(DelegateBreukenBewerking[] delegateBreukenBewerking, String[] operanden)
        {
            Breuk b = breuken[0];
            for (int i = 1; i < breuken.Count; i++) 
            {
                b = delegateBreukenBewerking[i-1](b, breuken[i]);
            }
            return b;
        }
    }
}
